import { BASE_URL } from "./config"

/**
 * HTTP请求工具类
 * @description 封装uni.request，支持请求拦截、响应拦截等功能
 */

// 默认配置
const defaultConfig = {
	baseURL: "", // 基础URL
	timeout: 10000, // 超时时间
	header: {
		"Content-Type": "application/json"
	},
	// 是否显示loading
	loading: true,
	// loading文字
	loadingText: "加载中..."
}

// 请求队列
let requestQueue = []

class Http {
	constructor(config = {}) {
		this.config = {
			...defaultConfig,
			...config
		}
	}

	/**
	 * 请求拦截器
	 * @param {Object} config 请求配置
	 * @returns {Object} 处理后的配置
	 */
	requestInterceptor(config) {
		// 显示loading
		if (config.loading) {
			uni.showLoading({
				title: config.loadingText,
				mask: true
			})
		}

		// 获取token
		const token = uni.getStorageSync("token")
		if (token) {
			config.header.Authorization = `Bearer ${token}`
		}

		// 将请求添加到队列
		requestQueue.push(config)

		return config
	}

	/**
	 * 响应拦截器
	 * @param {Object} response 响应数据
	 * @param {Object} config 请求配置
	 * @returns {Object} 处理后的响应数据
	 */
	responseInterceptor(response, config) {
		// 从队列中移除请求
		requestQueue = requestQueue.filter((item) => item !== config)

		// 隐藏loading
		if (config.loading && requestQueue.length === 0) {
			uni.hideLoading()
		}

		// 处理响应数据
		const { statusCode, data } = response

		// 请求成功
		if (statusCode >= 200 && statusCode < 300) {
			// 业务状态判断
			if (data.code === 0) {
				return data.data
			} else {
				return Promise.reject(data)
			}
		}

		// 请求失败
		return Promise.reject(response)
	}

	/**
	 * 发送请求
	 * @param {Object} config 请求配置
	 * @returns {Promise} 请求结果
	 */
	request(config) {
		// 合并配置
		config = {
			...this.config,
			...config,
			header: {
				...this.config.header,
				...config.header
			}
		}

		// 处理URL
		if (config.baseURL && !config.url.startsWith("http")) {
			config.url = config.baseURL + config.url
		}

		// 请求拦截
		config = this.requestInterceptor(config)

		// 发送请求
		return new Promise((resolve, reject) => {
			uni.request({
				...config,
				success: (response) => {
					try {
						const result = this.responseInterceptor(response, config)
						resolve(result)
					} catch (error) {
						reject(error)
					}
				},
				fail: (error) => {
					// 从队列中移除请求
					requestQueue = requestQueue.filter((item) => item !== config)

					// 隐藏loading
					if (config.loading && requestQueue.length === 0) {
						uni.hideLoading()
					}

					reject(error)
				}
			})
		})
	}

	/**
	 * GET请求
	 * @param {string} url 请求地址
	 * @param {Object} data 请求参数
	 * @param {Object} config 自定义配置
	 * @returns {Promise} 请求结果
	 */
	get(url, data = {}, config = {}) {
		return this.request({
			url,
			data,
			method: "GET",
			...config
		})
	}

	/**
	 * POST请求
	 * @param {string} url 请求地址
	 * @param {Object} data 请求参数
	 * @param {Object} config 自定义配置
	 * @returns {Promise} 请求结果
	 */
	post(url, data = {}, config = {}) {
		return this.request({
			url,
			data,
			method: "POST",
			...config
		})
	}

	/**
	 * PUT请求
	 * @param {string} url 请求地址
	 * @param {Object} data 请求参数
	 * @param {Object} config 自定义配置
	 * @returns {Promise} 请求结果
	 */
	put(url, data = {}, config = {}) {
		return this.request({
			url,
			data,
			method: "PUT",
			...config
		})
	}

	/**
	 * DELETE请求
	 * @param {string} url 请求地址
	 * @param {Object} data 请求参数
	 * @param {Object} config 自定义配置
	 * @returns {Promise} 请求结果
	 */
	delete(url, data = {}, config = {}) {
		return this.request({
			url,
			data,
			method: "DELETE",
			...config
		})
	}
}

// 创建实例
const http = new Http({
	baseURL: BASE_URL
})

export default http
